package com.wanxi.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.wanxi.dao.ProductDao;
import com.wanxi.dto.ResultDTO;
import com.wanxi.model.Product;
import com.wanxi.service.ProductService;
import com.wanxi.util.CreateOnlyID;
import com.wanxi.util.JsonCopy;
import com.wanxi.vo.ProductVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class ProductServiceImpl implements ProductService {
    @Autowired
    ProductDao productDao;
    @Autowired
    CreateOnlyID createOnlyId;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Override
    public ResultDTO findAllProduct() {
        List<Product> list=productDao.findAllProduct();
        if(list.size()>0){
            return ResultDTO.getDTO(list.size(),list);
        }
        return ResultDTO.builder().data(list).msg("no data").count(0).code(1).build();
    }

    @Override
    public ResultDTO findProductById(ProductVO productVO) {
        Product product= JsonCopy.copy(productVO,Product.class);
        Product p= productDao.findProductById(product);
        if(p!=null){
            return ResultDTO.getDTO(1,p);
        }
        return ResultDTO.builder().count(0).msg("error").code(1).build();
    }

    @Override
    public ResultDTO updateEnable(ProductVO productVO) {
        Product product= JsonCopy.copy(productVO,Product.class);
        int i= productDao.updateById(product);
        if(i==1){
            Long id = ((Product) findProductById(productVO).getData()).getProductType().getId();
            stringRedisTemplate.delete("productType:"+id);
            return ResultDTO.getDTO(i,productVO);
        }
        return ResultDTO.builder().data(productVO).count(0).code(1).msg("error").build();
    }

    @Override
    public ResultDTO addProduct(ProductVO productVO) {
        Product product= JsonCopy.copy(productVO,Product.class);
        Long productTypeId = product.getProductType().getId();
        if(productTypeId!=null && productTypeId ==0L){
            product.getProductType().setId(1L);
        }
        product.setId(createOnlyId.createId());
        productVO.setId(product.getId());
        int i= productDao.addProduct(product);
        if(i==1){
            Long id = ((Product) findProductById(productVO).getData()).getProductType().getId();
            stringRedisTemplate.delete("productType:"+id);
            return ResultDTO.getDTO(i,productVO);
        }
        return ResultDTO.builder().data(productVO).count(0).code(1).msg("error").build();
    }

    @Override
    public ResultDTO deleteProduct(ProductVO productVO) {
        Product product= JsonCopy.copy(productVO,Product.class);
        int i= productDao.deleteById(product);
        if(i==1){
            Long id = productVO.getId();
            stringRedisTemplate.delete("productType:"+id);
            return ResultDTO.getDTO(i,productVO);
        }
        return ResultDTO.builder().data(productVO).count(0).code(1).msg("error").build();
    }

    @Override
    public ResultDTO updateProduct(ProductVO productVO) {
        Product product= JsonCopy.copy(productVO,Product.class);
        Long productTypeId = product.getProductType().getId();
        if(productTypeId!=null && productTypeId ==0L){
            product.getProductType().setId(1L);
        }
        int i= productDao.updateProduct(product);
        if(i==1){
            Long id = ((Product) findProductById(productVO).getData()).getProductType().getId();
            stringRedisTemplate.delete("productType:"+id);
            return ResultDTO.getDTO(i,productVO);
        }
        return ResultDTO.builder().data(productVO).count(0).code(1).msg("error").build();
    }

    @Override
    public ResultDTO findProduct(ProductVO productVO) {
        Product product=JsonCopy.copy(productVO, Product.class);
        Long len = stringRedisTemplate.opsForList().size("productType:" + productVO.getProductType().getId());
//        判断redis中是否有数据
        if(len!=0){
//            返回redis中的数据,通过fastJson转换
            List<String> redisProduct = stringRedisTemplate.opsForList()
                    .range("productType:"+productVO.getProductType().getId(),0,len);
            List<Product> list= JSON.parseObject(redisProduct.toString(), new TypeReference<List<Product>>() {});
            return ResultDTO.getDTO(list.size(),list);
        }
//        没有则从数据库中找数据
        List<Product> list=productDao.findProduct(product);
        if(list.size()>0){
            Iterator<Product> iterator=list.iterator();
            while (iterator.hasNext()){
                Product p=iterator.next();
                if(p .getEnable()==0) {
                    iterator.remove();
                }
                else{
//                    将查到的数据放入redis
                    stringRedisTemplate.expire("productType:" + productVO.getProductType().getId(),300, TimeUnit.SECONDS);
                    stringRedisTemplate.opsForList()
                            .rightPush("productType:" + productVO.getProductType().getId(), JSON.toJSONString(p));
                }
            }
            return ResultDTO.getDTO(list.size(),list);
        }
        return ResultDTO.builder().data(list).msg("no data").count(0).code(1).build();
    }

    @Override
    public ResultDTO findProductBySome(ProductVO productVO) {
        Product product=JsonCopy.copy(productVO, Product.class);
        List<Product> list=productDao.findProductBySome(product);
        if(list.size()>0){
            return ResultDTO.getDTO(list.size(),list);
        }
        return ResultDTO.builder().data(list).msg("no data").count(0).code(1).build();
    }
}
